package com.itheima70.gooview.ui;

import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.OvershootInterpolator;

import com.itheima70.gooview.util.GeometryUtil;
import com.itheima70.gooview.util.Utils;

/**
 * 粘性控件
 * @author poplar
 *
 */
public class GooView extends View {

	private Paint paint;

	public GooView(Context context) {
		this(context, null);
	}

	public GooView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public GooView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		paint = new Paint();
		paint.setFlags(Paint.ANTI_ALIAS_FLAG); // 设置抗锯齿标记
		paint.setColor(Color.RED); // 设置画笔为红色
	}
	
	PointF mDragCenter = new PointF(80f, 80f); // 拖拽圆中心
	float mDragRadius = 16.0f;	// 拖拽圆半径
	PointF mStickCenter = new PointF(150f, 150f); // 固定圆中心
	float mStickRadius = 12.0f; // 固定圆半径
	
	PointF[] mStickPoints = new PointF[]{ // 固定圆两个附着点坐标
			new PointF(250f, 250f),
			new PointF(250f, 350f)
	};
	
	PointF[] mDragPoints = new PointF[]{ // 拖拽圆两个附着点坐标
				new PointF(50f, 250f),
				new PointF(50f, 350f)
	};
	
	PointF mControlPoint = new PointF(150f, 300f); // 控制点坐标
	private int statusBarHeight;
		
	@Override
	protected void onDraw(Canvas canvas) {
		
		// 计算变量
			// 计算固定圆的半径(根据两圆圆心距离)
			float tempStickRadius = computeStickRadius();
		
			// 计算四个附着点的坐标
			float yOffset = mStickCenter.y - mDragCenter.y;
			float xOffset = mStickCenter.x - mDragCenter.x;
			
			Double lineK = null;
			if(xOffset != 0){
				lineK = (double) (yOffset / xOffset);
			}
			// 计算出拖拽圆两个附着点的坐标
			mDragPoints = GeometryUtil.getIntersectionPoints(mDragCenter, mDragRadius, lineK);
			mStickPoints = GeometryUtil.getIntersectionPoints(mStickCenter, tempStickRadius, lineK);
		
			// 计算控制点坐标
			mControlPoint = GeometryUtil.getMiddlePoint(mDragCenter, mStickCenter);
		
		// 移动画布
		canvas.save(); // 保存当前状态
		canvas.translate(0, - statusBarHeight);
			
			// 把附着点绘制出来(参考用)
//			paint.setColor(Color.BLUE);
//			canvas.drawCircle(mDragPoints[0].x, mDragPoints[0].y, 3f, paint);
//			canvas.drawCircle(mDragPoints[1].x, mDragPoints[1].y, 3f, paint);
//			canvas.drawCircle(mStickPoints[0].x, mStickPoints[0].y, 3f, paint);
//			canvas.drawCircle(mStickPoints[1].x, mStickPoints[1].y, 3f, paint);
//			paint.setColor(Color.RED);
		
			// 绘制最大范围的圆环
			paint.setStyle(Style.STROKE);
			canvas.drawCircle(mStickCenter.x, mStickCenter.y, farestDistance, paint);
			paint.setStyle(Style.FILL);
		
		if(!isDisappear){
			// 没有消失的时候, 才绘制内容
			if(!isOutOfRange){
				// 没超出范围
				
				// 绘制中间连接部分
				Path path = new Path(); // 自定义路径/形状
				// 设置开始位置为点1
				path.moveTo(mStickPoints[0].x, mStickPoints[0].y);
				// 点1 -> 点2 画曲线
				path.quadTo(mControlPoint.x, mControlPoint.y, mDragPoints[0].x, mDragPoints[0].y);
				// 点2 -> 点3 画直线
				path.lineTo(mDragPoints[1].x, mDragPoints[1].y);
				// 点3 -> 点4 画曲线
				path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints[1].x, mStickPoints[1].y);
				path.close(); // 封闭曲线 (可以不调用, 会自动封闭)
				
				canvas.drawPath(path, paint); // 绘制曲线
				
				// 画固定圆
				canvas.drawCircle(mStickCenter.x, mStickCenter.y, tempStickRadius, paint);
			}

			// 画拖拽圆
			canvas.drawCircle(mDragCenter.x, mDragCenter.y, mDragRadius, paint);
		}
		
		
		canvas.restore(); // 恢复上一次保存的状态
	}
	
	float farestDistance = 80.0f;
	private boolean isOutOfRange = false; // 是否超出范围
	private boolean isDisappear = false; // 是否消失
	// 计算固定圆的半径(根据两圆圆心距离)
	private float computeStickRadius() {
		float distance = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);
		
		distance = Math.min(distance, farestDistance); // 0 -> 80
		
		// 0f -> 80.0f
		float percent = distance / farestDistance;
		System.out.println("percent: " + percent);
		
		// 0.0f -> 1.0f
		// 12.0f -> 3.0f
		
		return evaluate(percent, mStickRadius, mStickRadius * 0.25f);
	}
    public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		
		statusBarHeight = Utils.getStatusBarHeight(this);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		float x;
		float y;
		
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				isDisappear = false;
				isOutOfRange = false;
				
				x = event.getRawX();
				y = event.getRawY();
				updateDragCenter(x, y);
				
				break;
			case MotionEvent.ACTION_MOVE:
				x = event.getRawX();
				y = event.getRawY();
				updateDragCenter(x, y);
				
				// 判断距离
				float d = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);
				if(d > farestDistance){
					isOutOfRange = true;
					invalidate();
				}
				
				break;
			case MotionEvent.ACTION_UP:
				if(isOutOfRange){
					// 刚刚超出范围了
					float distance = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);
					if(distance > farestDistance){
						// 超出范围
						isDisappear  = true;
						invalidate();
					}else {
						// 没超出范围
						updateDragCenter(mStickCenter.x, mStickCenter.y);
					}
				}else {
					final PointF startPoint = new PointF(mDragCenter.x, mDragCenter.y);
					final PointF endPoint = mStickCenter;
					
					// 刚刚没超出范围了
					ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
					
					animator.addUpdateListener(new AnimatorUpdateListener() {
						
						@Override
						public void onAnimationUpdate(ValueAnimator animation) {
							float fraction = animation.getAnimatedFraction();
							// 0.0f -> 1.0f
							System.out.println("fraction: " + fraction);
							
							PointF p = GeometryUtil.getPointByPercent(startPoint, endPoint, fraction);
							updateDragCenter(p.x, p.y);
						}
					});
					animator.setInterpolator(new OvershootInterpolator(4));
					animator.setDuration(500);
					animator.start();
					
				}
				
				break;
			default:
				break;
		}
		
		return true;
	}

	/**
	 * 更新拖拽圆圆心坐标, 重绘界面
	 * @param x
	 * @param y
	 */
	private void updateDragCenter(float x, float y) {
		mDragCenter.set(x, y);
		invalidate();
	}

}
